from copy import deepcopy
from typing import TypeVar, Generic, Optional

from pydantic import Field, validator
from pydantic.generics import GenericModel

SUCCESS = "SUCCESS"
FAILED = "FAILED"


class ReturnInfo(object):
    def __init__(self):
        self.status = FAILED  # SUCCESS FAILED
        self.msg_code = ''
        self.msg = ''
        self.data = {}

    def todict(self):
        # __dict__ 是字典，不进行转化无法输出
        from app_main import request_ctx_var
        try_his = request_ctx_var.get().state.try_his
        if self.status == FAILED and try_his:
            tmp_data = deepcopy(self.data)
            self.data = {"data": tmp_data}
            self.data["try_his"] = try_his
        return self.__dict__


DataT = TypeVar('DataT')


# = '' 当没有默认参数，body就必须有该字段
class InputInfoModel(GenericModel, Generic[DataT]):
    proxy: Optional[str] = ''
    input_code: str = ''
    input_msg: str = ''
    data: DataT


# class GConfig(object):
#     ip: str = ""
#     port: str = ""
#     app_name: str = ""


class SaveStepMongoModel(GenericModel, Generic[DataT]):
    id: str = Field("", alias="_id")
    product: str = ""  # 数据来源标识 cnki
    types: str = ""  # qk
    step_name: str = ""  # 步骤名g_jid
    # 为了维护老的结构(task_name和task_name)
    task_name: str = ""
    step_info: DataT = {}  # 步骤信息
    update_time: str = ""
    create_time: str = ""
    editions: str = ""

    @validator('*', pre=True)
    def deal_none(cls, v, field):
        if v is None or v == {} or v == "":
            return field.default
        return v

    @validator('update_time', 'create_time', pre=True)
    def split_str(cls, v):
        return str(v)


class DetailModel(GenericModel, Generic[DataT]):
    id: str = Field("", alias="_id")
    step_name: str = ""  # 步骤名g_jid
    # 为了维护老的结构(task_name和task_name)
    task_name: str = ""
    step_info: DataT = {}  # 步骤信息
    update_time: str = ""
    create_time: str = ""
    downdate = ""

    @validator('*', pre=True)
    def deal_none(cls, v, field):
        if v is None or v == {} or v == "":
            return field.default
        return v

    @validator('update_time', 'create_time', pre=True)
    def split_str(cls, v):
        return str(v)
